/*
 * ---------------------------------------------------------------------
 * Copyright (c) 2014, 2015 All Right Reserved
 * This software is developed for study and improve coding skill ...
 *
 * Project:  Excellent Coding < EC >
 *
 * ecQueue.h
 * This file for all EC queue data struct util tools.
 *
 * Eamil:   epengao@126.com
 * Author:  Peter Gao
 * Version: Intial first version.
 * --------------------------------------------------------------------
 */
#ifndef EC_QUEUE_H
#define EC_QUEUE_H

#include "ecNode.h"

namespace ec
{

template<typename T>
class ecQueue
{
public:
    ecQueue();
    virtual ~ecQueue();
    virtual EC_U32 AddItemToTail(T* pInData);
    virtual EC_U32 DeleteFromHead(T* pOutData);

protected:
    ecNode<T>*    m_pHead;
    ecNode<T>*    m_pTail;
};

template<typename T>
ecQueue<T>::ecQueue()
:m_pHead(EC_NULL)
,m_pTail(EC_NULL)
{
}

template<typename T>
ecQueue<T>::~ecQueue()
{
    ecNode<T>* pCurr = m_pHead;
    ecNode<T>* pNext = EC_NULL;
    while(pCurr)
    {
        pNext = pCurr->m_pNext;
        delete pCurr;
        pCurr = pNext;
    }
}

template<typename T>
EC_U32 ecQueue<T>::AddItemToTail(T* pInData)
{
    EC_U32 nRet = EC_Err_None;

    ecNode<T>* pNode = new ecNode<T>(pInData);
    if(pNode)
    {
        if(EC_NULL != m_pTail)
        {
            m_pTail->m_pNext = pNode;
            m_pTail = pNode;
        }
        else
        {
            m_pTail = pNode;
            m_pHead = pNode;
        }
    }
    else
        nRet = EC_Err_Memory_Overflow;

    return nRet;
}

template<typename T>
EC_U32 ecQueue<T>::DeleteFromHead(T* pOutData)
{
    EC_U32 nRet = EC_Err_None;
    if(EC_NULL != m_pHead)
    {
        ecNode<T>* pNode = m_pHead;
        if(m_pHead == m_pTail)
        {
            m_pHead = EC_NULL;
            m_pTail = EC_NULL;
        }
        else
            m_pHead = m_pHead->m_pNext;

        *pOutData = pNode->m_sData;
        delete pNode;
    }
    else
        nRet = EC_Err_DataNotExist;

    return nRet;
}
} /* namespace ec */
#endif /* EC_QUEUE_H */